/**************************************************************************************
 *  Copyright (c)  2010  Leszek Karcz, Changmin Bae.
 *  Permission is granted to copy, distribute and/or modify this document
 *  under the terms of the GNU Free Documentation License, Version 1.3
 *  or any later version published by the Free Software Foundation;
 *  with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
 *  A copy of the license is included in the section entitled "GNU
 *  Free Documentation License". 
 **************************************************************************************/
package data.tileables;
import data.Player;
import data.UnitOwner;

/**************************************************************************************
 * Author(s): Leszek Karcz, Changmin Bae
 * Base structure for all player units that can be put inside a tile
 **************************************************************************************/
public abstract class Unit extends Controllable
{
	private int movementTicks;
	private int direction; //01 - up; 1 - up-right; 2 - down-right; 3 - down; 4 - down-left; 5 - up-left
	private Controllable base;
	private UnitOwner owner;
	
	/**************************************************************************************
	 * Author(s): Leszek Karcz
	 * Unit constructor
	 **************************************************************************************/
	public Unit(int ID, int supertypeID, Player player)
	{
		super(ID, supertypeID, player);
		this.setType("Unit");
		this.setDisplayLevel(0);
		this.setMovementTicks(1);
		this.setDirection(0);
		this.base = player.getBase();
		owner = player.getBase();
	}	
	
	public Unit(int ID, int supertypeID, Player player, UnitOwner unit){
		super(ID, supertypeID, player);
		owner = unit;
	}
	
	/**************************************************************************************
	 * Author(s): Changmin Bae
	 * executes first mission in mission queue
	 **************************************************************************************/
	public void execute()
	{
		
		if(!missionQueue.isEmpty())
		{
			int flag = missionQueue.peekFirst().execute();
			if(flag == 1)
			{
				missionQueue.removeFirst();
			}
			else if(flag == 2)
			{
				if(missionQueue.getSize() > 1)
				{
					missionQueue.removeFirst();
				}
			}
		}		
		allocate();
	}
	
	/**************************************************************************************
	 * Author(s): Leszek Karcz
	 * returns how many tick it takes to move by 1 tile
	 **************************************************************************************/
	public int getMovementTicks()
	{
		return this.movementTicks;
	}
	
	/**************************************************************************************
	 * Author(s): Leszek Karcz
	 * sets how many tick it takes to move 1 tile
	 **************************************************************************************/
	protected void setMovementTicks(int movementTicks)
	{
		this.movementTicks=movementTicks;
	}
	
	/**************************************************************************************
	 * Author(s): Leszek Karcz
	 * returns the direction the unit is facing
	 **************************************************************************************/
	public int getDirection()
	{
		return this.direction;
	}
	
	/**************************************************************************************
	 * Author(s): Leszek Karcz
	 * sets the direction the unit is facing
	 **************************************************************************************/
	public void setDirection(int direction)
	{
		if((direction>=0) && (direction<=5))
		{
			this.direction=direction;
		}
	}
	/**************************************************************************************
	 * Author(s): Leszek Karcz
	 * get image file name for the structure according to its level of completion
	 **************************************************************************************/
	public UnitOwner getOwner()
	{
		return owner;
	}
	
	/**************************************************************************************
	 * Author(s): Leszek Karcz
	 * get image file name for the structure according to its level of completion
	 **************************************************************************************/
	public String getImage()
	{
		return super.getImage()+"_"+this.getDirection();
	}
	
	/**************************************************************************************
	 * Author(s): Leszek Karcz
	 * get icon file  name, highlight file name
	 **************************************************************************************/
	public String[] getImageData(int playerID)
	{
		return new String[]{((this.getPlayerID()==playerID) && (this.equals(this.player.getSelected())) ? "pselected_unit_h" : "p"+this.getPlayerID()+"_unit_h"),this.getImage(),""+this.getHealthPercentage()};
	}
	
	/**************************************************************************************
	 * Author(s): Leszek Karcz
	 * Return the stats of units with applied area bonuses
	 **************************************************************************************/
	public int[] getStats()
	{
		int[] stats=super.getStats();
		int armorBonus=this.player.getAreaBonus(this.getX(), this.getY());
		if(armorBonus>0)
		{
			stats[2]=stats[2]+armorBonus;
		}		
		return stats;
	}	
	
	/**************************************************************************************
	 * Author(s): Leszek Karcz
	 * Return the stats text of units with applied area bonuses
	 **************************************************************************************/
	public String[] getStatsText()
	{
		int armorBonus=this.player.getAreaBonus(this.getX(), this.getY());
		int[] stats=this.getBaseStats();		
		return new String[]{"ID: "+this.getID(),
							"Health: "+(int)stats[0]+"/"+stats[1],
							"Armor: "+stats[2]+((armorBonus>0) ? (" + "+armorBonus) : ""),
							"Offensive Damage: "+stats[3],
							"Defensive Damage: "+stats[4],
							"Movement: "+this.getMovementTicks(),
							"Vision: "+this.getVisionRadius(),
							"Upkeep: "+this.getUpkeep()[0]+" "+this.getUpkeep()[1]+" "+this.getUpkeep()[2],
							"State: "+this.getStateText(),
							"",
							"Mission: "+this.getCurrentMissionName()};
	}
	
	protected void setOwner(UnitOwner unit){
		this.owner = unit;
	}
	
	protected void removeOwner(){
		if(this.owner!=null)
		{
			this.owner.removeUnit(this);
		}
		this.owner = player.getBase();
	}
	
	
	/**************************************************************************************
	 * Author(s): Eric 
	 * returns base upkeep with mods for units
	 **************************************************************************************/
	public int[] getUpkeep()
	{
		int [] base = super.getUpkeep();
		
		if(this.getState() == 2){
			base[FOOD] *= 0.75;
			base[METAL] *= 0.75;
			base[ENERGY] *= 0.75;
		}
		
		return base;	
	}
	
	/**************************************************************************************
	 * Author(s): Eric 
	 * returns the state ofthe controllable and accounts for standby
	 **************************************************************************************/
	public int getState(){
		if(!(this.owner instanceof Rally) && !(this instanceof Rally) && super.getState() == 1)
			return 2;
		
		return super.getState();
	}
	
	/**************************************************************************************
	 * Author(s): Eric 
	 * returns the state ofthe controllable and accounts for standby
	 **************************************************************************************/
	public String getStateText(){
		if(this.getState() == 2)
			return "Standby";
		
		return super.getStateText();
	}
	
	/**************************************************************************************
	 * Author(s): Leszek Karcz
	 * kills of the unit
	 **************************************************************************************/
	public void die()
	{
		super.die();
		this.removeOwner();
	}
	
}
